/*
 * This file is part of the Sx Framework Library.
 * 
 * Copyright (C) 2013 University of Colorado Denver
 * <min.choi@ucdenver.edu> <shane.transue@ucdenver.edu>
 * 
 * Permission is hereby granted, free of charge, to any person obtaining a copy 
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 
 * copies of the Software, and to permit persons to whom the Software is 
 * furnished to do so, subject to the following conditions:
 * 
 * The above copyright notice and this permission notice shall be included in 
 * all copies or substantial portions of the Software.
 * 
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 
 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 
 * DEALINGS IN THE SOFTWARE.
 */
#include <sxBinaryFileWriter.h>
#include <iostream>

const static char NULL_CHAR = '\0';

Sx::File::BinaryFileWriter::BinaryFileWriter() {}

Sx::File::BinaryFileWriter::~BinaryFileWriter() {
	if ( this->file.is_open() == true ) this->file.close();
}

bool Sx::File::BinaryFileWriter::open(const String& fileName) {
	if ( this->file.is_open() == true ) this->file.close();
	this->file.open(fileName.toAscii().constData(), std::ios::out | std::ios::binary);
	return true;
}

bool Sx::File::BinaryFileWriter::write(char byte) {
	if ( this->file.is_open() == false ) {
		std::cout << "[BinaryFileWritter:write] Error: "
					 "Binary file is not open." << std::endl;
		return false;
	}

	this->file.write(&byte, sizeof(char));
	return true;
}

bool Sx::File::BinaryFileWriter::write(char* buffer, unsigned int length, bool appendNull) {
	if ( this->file.is_open() == false ) {
		std::cout << "[BinaryFileWriter:write] Error: "
					 "Binary file is not open." << std::endl;
		return false;
	}

	this->file.write(buffer, sizeof(char) * length);
	if ( appendNull == true ) this->write(NULL_CHAR);
	return true;
}

bool Sx::File::BinaryFileWriter::write(const char* buffer, unsigned int length) {
	if ( this->file.is_open() == false ) {
		std::cout << "[BinaryFileWriter:write] Error: "
					 "Binary file is not open." << std::endl;
		return false;
	}

	this->file.write(buffer, sizeof(char) * length);
	this->write(NULL_CHAR);
	return true;
}

bool Sx::File::BinaryFileWriter::write(short value) {
	if ( this->file.is_open() == false ) {
		std::cout << "[BinaryFileWriter:write] Error: "
					 "Binary file is not open." << std::endl;
		return false;
	}

	this->file.write(reinterpret_cast<char*>(&value), sizeof(short));
	return true;
}

bool Sx::File::BinaryFileWriter::write(short* buffer, unsigned int length) {
	if ( this->file.is_open() == false ) {
		std::cout << "[BinaryFileWriter:write] Error: "
					 "Binary file is not open." << std::endl;
		return false;
	}

	this->file.write(reinterpret_cast<char*>(buffer), sizeof(short) * length);
	return true;
}

bool Sx::File::BinaryFileWriter::write(const short* buffer, unsigned int length) {
	if ( this->file.is_open() == false ) {
		std::cout << "[BinaryFileWriter:write] Error: "
					 "Binary file is not open." << std::endl;
		return false;
	}

	this->file.write(reinterpret_cast<const char*>(buffer), 
					 sizeof(short) * length);
	return true;
}

bool Sx::File::BinaryFileWriter::write(int value) {
	if ( this->file.is_open() == false ) {
		std::cout << "[BinaryFileWriter:write] Error: "
					 "Binary file is not open." << std::endl;
		return false;
	}

	this->file.write(reinterpret_cast<char*>(&value), sizeof(int));
	return true;
}

bool Sx::File::BinaryFileWriter::write(int* buffer, unsigned int length) {
	if ( this->file.is_open() == false ) {
		std::cout << "[BinaryFileWriter:write] Error: "
					 "Binary file is not open." << std::endl;
		return false;
	}

	this->file.write(reinterpret_cast<char*>(buffer), sizeof(int) * length);
	return true;
}

bool Sx::File::BinaryFileWriter::write(const int* buffer, unsigned int length) {
	if ( this->file.is_open() == false ) {
		std::cout << "[BinaryFileWriter:write] Error: "
					 "Binary file is not open." << std::endl;
		return false;
	}

	this->file.write(reinterpret_cast<const char*>(buffer), 
					 sizeof(int) * length);
	return true;
}

bool Sx::File::BinaryFileWriter::write(long value) {
	if ( this->file.is_open() == false ) {
		std::cout << "[BinaryFileWriter:write] Error: "
					 "Binary file is not open." << std::endl;
		return false;
	}

	this->file.write(reinterpret_cast<char*>(&value), sizeof(long));
	return true;
}

bool Sx::File::BinaryFileWriter::write(long* buffer, unsigned int length) {
	if ( this->file.is_open() == false ) {
		std::cout << "[BinaryFileWriter:write] Error: "
					 "Binary file is not open." << std::endl;
		return false;
	}

	this->file.write(reinterpret_cast<char*>(buffer), sizeof(long) * length);
	return true;
}

bool Sx::File::BinaryFileWriter::write(const long* buffer, unsigned int length) {
	if ( this->file.is_open() == false ) {
		std::cout << "[BinaryFileWriter:write] Error: "
					 "Binary file is not open." << std::endl;
		return false;
	}

	this->file.write(reinterpret_cast<const char*>(buffer), 
					 sizeof(long) * length);
	return true;
}

bool Sx::File::BinaryFileWriter::write(float value) {
	if ( this->file.is_open() == false ) {
		std::cout << "[BinaryFileWriter:write] Error: "
					 "Binary file is not open." << std::endl;
		return false;
	}

	this->file.write(reinterpret_cast<char*>(&value), sizeof(float));
	return true;
}

bool Sx::File::BinaryFileWriter::write(float* buffer, unsigned int length) {
	if ( this->file.is_open() == false ) {
		std::cout << "[BinaryFileWriter:write] Error: "
					 "Binary file is not open." << std::endl;
		return false;
	}

	this->file.write(reinterpret_cast<char*>(buffer), sizeof(float) * length);
	return true;
}

bool Sx::File::BinaryFileWriter::write(const float* buffer, unsigned int length) {
	if ( this->file.is_open() == false ) {
		std::cout << "[BinaryFileWriter:write] Error: "
					 "Binary file is not open." << std::endl;
		return false;
	}

	this->file.write(reinterpret_cast<const char*>(buffer), 
					 sizeof(float) * length);
	return true;
}


bool Sx::File::BinaryFileWriter::write(double value) {
	if ( this->file.is_open() == false ) {
		std::cout << "[BinaryFileWriter:write] Error: "
					 "Binary file is not open." << std::endl;
		return false;
	}

	this->file.write(reinterpret_cast<char*>(&value), sizeof(double));
	return true;
}

bool Sx::File::BinaryFileWriter::write(double* buffer, unsigned int length) {
	if ( this->file.is_open() == false ) {
		std::cout << "[BinaryFileWriter:write] Error: "
					 "Binary file is not open." << std::endl;
		return false;
	}

	this->file.write(reinterpret_cast<char*>(buffer), sizeof(double) * length);
	return true;
}

bool Sx::File::BinaryFileWriter::write(const double* buffer, unsigned int length) {
	if ( this->file.is_open() == false ) {
		std::cout << "[BinaryFileWriter:write] Error: "
					 "Binary file is not open." << std::endl;
		return false;
	}

	this->file.write(reinterpret_cast<const char*>(buffer), 
					 sizeof(double) * length);
	return true;
}

bool Sx::File::BinaryFileWriter::write(String string) {
	if ( this->file.is_open() == false ) {
		std::cout << "[BinaryFileWriter:write] Error: "
					 "Binary file is not open." << std::endl;
		return false;
	}

	this->file.write(reinterpret_cast<const char*>(string.toAscii().constData()),
					 sizeof(char) * string.length());
	this->write(NULL_CHAR);
	return true;
}

bool Sx::File::BinaryFileWriter::close() {
	if ( this->file.is_open() == false ) {
		std::cout << "[BinaryFileWriter:write] Error: "
					 "Binary file is not open." << std::endl;
		return false;
	}

	this->file.close();
	return true;
}
